package org.harsh.common.crypt;

import org.harsh.common.Config;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


/**
 * Created by liuhaibo on 2024/7/15.
 */
public class RsaCrypt extends AbsCrypt{

    private static final String RSA_KEY_ALGORITHM ="RSA";
    private static final String RSA_SIGNATURE_ALGORITHM = "SHA1withRSA";
    private static final String RSA2_SIGNATURE_ALGORITHM = "SHA256withRSA";
    private static final int KEY_SIZE = 2048;
    byte[] pub_key;
    byte[] pri_key;

    public RsaCrypt() throws NoSuchAlgorithmException {
        KeyPairGenerator keygen;
        try {
            keygen = KeyPairGenerator.getInstance(RSA_KEY_ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("RSA初始化密钥出现错误,算法异常");
        }
        SecureRandom secrand = new SecureRandom();
        //初始化随机产生器
        secrand.setSeed(Config.DEFAULT_KEY.getBytes(Config.DEFAULT_CHARSET));
        //初始化密钥生成器
        keygen.initialize(KEY_SIZE, secrand);
        KeyPair keyPair = keygen.genKeyPair();
        //获取公钥并转成base64编码
        pub_key = keyPair.getPublic().getEncoded();
        //获取私钥并转成base64编码
        pri_key = keyPair.getPrivate().getEncoded();
    }

    @Override
    public void init() {
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pub_key);
        //返回转换指定算法的KeyFactory对象
        KeyFactory keyFactory = null;
        try {
            keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
            PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
            //根据转换的名称获取密码对象Cipher（转换的名称：算法/工作模式/填充模式）
            enCipher = Cipher.getInstance(keyFactory.getAlgorithm());
            //用公钥初始化此Cipher对象（加密模式）
            enCipher.init(Cipher.ENCRYPT_MODE, publicKey);

            enCipher = Cipher.getInstance(keyFactory.getAlgorithm());
            //用公钥初始化此Cipher对象（加密模式）
            enCipher.init(Cipher.ENCRYPT_MODE, publicKey);

            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pri_key);
            //根据PKCS8编码密钥规范产生私钥对象
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
            //根据转换的名称获取密码对象Cipher（转换的名称：算法/工作模式/填充模式）
            deCipher = Cipher.getInstance(keyFactory.getAlgorithm());
            //用私钥初始化此Cipher对象（解密模式）
            deCipher.init(Cipher.DECRYPT_MODE, privateKey);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException(e);
        } catch (NoSuchPaddingException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        }

    }
}
